r'''

	Der TCP/IP Server

'''

import socket
import serverinfo
import json
import DiffieHellman
import xtea

class TCPServer():
    '''
        Die Klasse ``TCPServer`` stellt einen Server zur Verfuegung. 
    '''
    def __init__(self):
        '''
            Hier werden Objekte der verschiedenen Klassen angelegt. 
            
            * dhobj realisiert das Diffie-Hellman-Protokoll
            * xtea_obj relasiert die Verschluesselung der Daten durch den XTEA-Algorithmus
            * Die Parameter ``HOST`` und ``PORT`` werden aus der Datei :py:mod:`diffieHellmanXTEA.serverinfo` gelesen.
			
        '''
        self.dhobj = DiffieHellman.DHCrypt()
        self.xtea_obj = xtea.XTEA()
        self.HOST = serverinfo.HOST
        self.PORT = serverinfo.PORT
        self.conn = None
        self.adr = None
    
    def createConn(self):
        '''
            Die Funktion ``createConn()`` stellt einen Socket zur Verfuegung und wartet auf eine Nachricht
            vom TCPClient.
        '''
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind((self.HOST, self.PORT))
        s.listen(1)
        self.conn, self.addr = s.accept()
           
    
        
        
    def handle(self):
        '''
            Die Funktion reagiert auf die Nachrichten des Clients. Da die Nachrichten in Form von
            JSON gekapselt un duebertragen werden, muss die Nachricht geparst werden. Damit der Server
            mehrere Nachrichten empfangen kann, muss man die Nachrichten in einer ``while``-Schleife abfangen.
            Wenn keine Nachrichten mehr eintreffen, wird die Verbindung geschlossen.
        '''
        while True:
            self.data = self.conn.recv(1024)
            if not self.data: break
                
            
            print self.data
            key , value = self.parseInput(self.data)
            if(key == "Handshake1"):
                self.dhobj.genCommonKey(value) 
                serverhandshake = self.dhobj.handSchack()
                response = json.dumps({"Handshake2": serverhandshake})
                self.conn.send(response)
            elif (key == "Message"):
                self.clientDaten = value;
                response = self.decodeMsg()
                confStr = "Erhalten"
                confirm = self.dhobj.xteaEncode(confStr)
                #confirm = self.xtea_obj.strencode(self.dhobj.key, confStr)
                response = json.dumps({"Confirm":confirm})
                self.conn.send(response) 
        self.conn.close()
        
    

    def parseInput(self,data):
        '''
            Die Funktion parst die Nachricht des Clients und gibt als Ergebnis die Parameter key und value
            zueruck (Dictionary).
        '''
        key = None
        value = None
        job = json.loads(data)
        value = job.get("Handshake1")
        if(value is None): # wenn kein HS1:
            value = job.get("Message")
            if not(value is None): # also hier ist ein message -> entschluesselt es 
                key = "Message" # return nur roh daten, hier passiert keine Datenverabrbeitung
                return(key,value)
            else: # ungultig faelle
                pass
        else:# HS1 ist in value
            key = "Handshake1"
            return (key,value)
            pass
            
    def decodeMsg(self):
        '''
            Die Funktion wird zur Entschluesselung der erhaltenen Daten, die vom Server gesendet werden,
            gebraucht und gibt die entschluesselte Nachricht zurueck.
        '''
        #return self.xtea_obj.strdecode(self.dhobj.key, self.clientDaten)
        r = self.dhobj.xteaDecode(self.clientDaten)
        return r
        #print r
        
    
    def JSON_Handshake2(self):
        '''
            Generiert die Handshake der Serverseite aus und gibt einen String im JSON Format zurueck.
        '''
        jobj = json.dumps({"Handshake2": self.dhobj.handSchack()})
        return jobj
    
        

       

        
        
if __name__ == "__main__":

    server = TCPServer()
    server.createConn()
    server.handle()
